home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -in_the_mag- / emulation / amiga / uae-0.7.0b2 / src / zfile.c < prev   
C/C++ Source or Header  |  1998-01-20  |  5KB  |  247 lines

  1.  /*
  2.   * UAE - The Un*x Amiga Emulator
  3.   *
  4.   * routines to handle compressed file automatically
  5.   *
  6.   * (c) 1996 Samuel Devulder, Tim Gunn
  7.   */
  8.  
  9. #include "sysconfig.h"
  10. #include "sysdeps.h"
  11.  
  12. #include "config.h"
  13. #include "options.h"
  14. #include "zfile.h"
  15.  
  16. #ifdef USE_ZFILE
  17.  
  18. #ifdef AMIGA
  19. extern char *amiga_dev_path;   /* dev: */
  20. extern char *ixemul_dev_path;  /* /dev/ */
  21. extern int readdevice (const char *, char *);
  22. #endif
  23.  
  24. static struct zfile
  25. {
  26.     struct zfile *next;
  27.     FILE *f;
  28.     char name[L_tmpnam];
  29. } *zlist;
  30.  
  31. /*
  32.  * called on exit()
  33.  */
  34. void zfile_exit(void)
  35. {
  36.     struct zfile *l;
  37.     
  38.     while ((l = zlist)) {
  39.     zlist = l->next;
  40.     fclose(l->f);
  41.     unlink(l->name); /* sam: in case unlink() after fopen() fails */
  42.     free(l);
  43.     }
  44. }
  45.  
  46. /*
  47.  * fclose() but for a compressed file
  48.  */
  49. int zfile_close(FILE *f)
  50. {
  51.     struct zfile *pl = NULL;
  52.     struct zfile *l  = zlist;
  53.     int ret;
  54.  
  55.     while(l && l->f!=f) {
  56.     pl = l;
  57.     l = l->next;
  58.     }
  59.     if (!l)
  60.     return fclose(f);
  61.     ret = fclose(l->f);
  62.     
  63.     if(!pl)
  64.     zlist = l->next;
  65.     else
  66.     pl->next = l->next;
  67.     free(l);
  68.  
  69.     return ret;
  70. }
  71.  
  72. /*
  73.  * gzip decompression
  74.  */
  75. static int gunzip (const char *decompress, const char *src, const char *dst)
  76. {
  77.     char cmd[1024];
  78.     if (!dst) 
  79.     return 1;
  80.     sprintf (cmd, "%s -c -d %s >%s", decompress, src, dst);
  81.     return !system (cmd);
  82. }
  83.  
  84. /*
  85.  * lha decompression
  86.  */
  87. static int lha (const char *src, const char *dst)
  88. {
  89.     char cmd[1024];
  90.     if (!dst)
  91.     return 1;
  92. #if defined(AMIGA)
  93.     sprintf (cmd, "lha -q -N p %s >%s", src, dst);
  94. #else
  95.     sprintf (cmd, "lha pq %s >%s", src, dst);
  96. #endif
  97.     return !system (cmd);
  98. }
  99.  
  100. /*
  101.  * (pk)unzip decompression
  102.  */
  103. static int unzip(const char *src, const char *dst)
  104. {
  105.     char cmd[1024];
  106.     if (!dst)
  107.     return 1;
  108. #if defined AMIGA || defined __unix
  109.     sprintf (cmd, "unzip -p %s '*.adf' >%s", src, dst);
  110.     return !system (cmd);
  111. #endif
  112. }
  113.  
  114. /*
  115.  * decompresses the file (or check if dest is null)
  116.  */
  117. static int uncompress(const char *name, char *dest)
  118. {
  119.     char *ext = strrchr (name, '.');
  120.     char nam[1024];
  121.  
  122.     if (ext != NULL && access (name, 0) >= 0) {
  123.     ext++;
  124.     if (strcasecmp (ext, "z") == 0
  125.         || strcasecmp (ext, "gz") == 0
  126.         || strcasecmp (ext, "adz") == 0
  127.         || strcasecmp (ext, "roz") == 0)
  128.         return gunzip ("gzip", name, dest);
  129.     if (strcasecmp (ext, "bz") == 0)
  130.         return gunzip ("bzip", name, dest);
  131.     if (strcasecmp (ext, "bz2") == 0)
  132.         return gunzip ("bzip2", name, dest);
  133.  
  134. #ifndef __DOS__
  135.     if (strcasecmp (ext, "lha") == 0
  136.         || strcasecmp (ext, "lzh") == 0)
  137.         return lha (name, dest);
  138.     if (strcasecmp (ext, "zip") == 0)
  139.          return unzip (name, dest);
  140. #endif
  141.     }
  142.  
  143.     if (access (strcat (strcpy (nam, name), ".z"), 0) >= 0
  144.     || access (strcat (strcpy (nam, name), ".Z"), 0) >= 0
  145.     || access (strcat (strcpy (nam, name), ".gz"), 0) >= 0
  146.     || access (strcat (strcpy (nam, name), ".GZ"), 0) >= 0
  147.     || access (strcat (strcpy (nam, name), ".adz"), 0) >= 0
  148.     || access (strcat (strcpy (nam, name), ".roz"), 0) >= 0)
  149.     return gunzip ("gzip", nam, dest);
  150.  
  151.     if (access (strcat (strcpy (nam, name), ".bz"), 0) >= 0
  152.     || access (strcat (strcpy (nam, name), ".BZ"), 0) >= 0)
  153.     return gunzip ("bzip", nam, dest);
  154.  
  155.     if (access (strcat (strcpy (nam, name), ".bz2"), 0) >= 0
  156.     || access (strcat (strcpy (nam, name), ".BZ2"), 0) >= 0)
  157.     return gunzip ("bzip2", nam, dest);
  158.  
  159. #ifndef __DOS__
  160.     if (access (strcat (strcpy (nam, name), ".lha"), 0) >= 0
  161.     || access (strcat (strcpy (nam, name), ".LHA"), 0) >= 0
  162.     || access (strcat (strcpy (nam, name), ".lzh"), 0) >= 0
  163.     || access (strcat (strcpy (nam, name), ".LZH"), 0) >= 0)
  164.     return lha (nam, dest);
  165.  
  166.     if (access (strcat (strcpy (nam, name),".zip"),0) >= 0
  167.     || access (strcat (strcpy (nam, name),".ZIP"),0) >= 0)
  168.        return unzip (nam, dest);
  169. #endif
  170.  
  171. #if defined(AMIGA)
  172.     /* sam: must be before real access to work */
  173.     if (!strnicmp (name, ixemul_dev_path, strlen (ixemul_dev_path)))
  174.     return readdevice (name + strlen (ixemul_dev_path), dest);
  175.     if (!strnicmp (name, amiga_dev_path, strlen (amiga_dev_path)))
  176.     return readdevice (name + strlen (amiga_dev_path), dest);
  177. #endif
  178.  
  179.     return 0;
  180. }
  181.  
  182. /*
  183.  * fopen() for a compressed file
  184.  */
  185. FILE *zfile_open(const char *name, const char *mode)
  186. {
  187.     struct zfile *l;
  188.     int fd = 0;
  189.  
  190.     if(! uncompress (name, NULL))
  191.     return fopen (name, mode);
  192.     l = malloc (sizeof *l);
  193.     if (!l)
  194.     return NULL;
  195.  
  196.     tmpnam(l->name);
  197.  
  198.     /* On the amiga this would make ixemul loose the break handler */
  199.     /* ==> fixed in exmul v4.6 */
  200.     fd = creat(l->name, 0666);
  201.     if (fd < 0)
  202.     return NULL;
  203.  
  204.     if (!uncompress (name, l->name)) {
  205.     free(l);
  206.     close (fd);
  207.     unlink(l->name);
  208.     return NULL;
  209.     }
  210.  
  211.     l->f = uae_fopen_del (l->name, mode);
  212.  
  213.     close (fd);
  214.  
  215.     if (l->f == NULL) {
  216.     free(l);
  217.     return NULL;
  218.     }
  219.  
  220.     l->next = zlist;
  221.     zlist   = l;
  222.  
  223.     return l->f;
  224. }
  225.  
  226. #else
  227.  
  228. /*
  229.  * Stubs for machines that this doesn't work on.
  230.  */
  231.  
  232. void zfile_exit(void)
  233. {
  234. }
  235.  
  236. int zfile_close(FILE *f)
  237. {
  238.     return fclose(f);
  239. }
  240.  
  241. FILE *zfile_open(const char *name, const char *mode)
  242. {
  243.     return fopen(name, mode);
  244. }
  245.  
  246. #endif
  247.